package com.trw.trp.action;

import java.awt.Color;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;

import com.lowagie.text.Document;
import com.lowagie.text.Font;
import com.lowagie.text.Image;
import com.lowagie.text.Phrase;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;
import com.trw.trp.AppConfiguration;
import com.trw.trp.bean.ModelBean;
import com.trw.trp.bean.ModelDetail;
import com.trw.trp.bean.OrderBean;
import com.trw.trp.bean.OrderHistoryBean;
import com.trw.trp.bean.OrderTemplateBean;
import com.trw.trp.bean.PropertyBean;
import com.trw.trp.bean.SearchCriteriaBean;
import com.trw.trp.bean.UserBean;
import com.trw.trp.dao.DaoFactory;
import com.trw.trp.dao.ModelDao;
import com.trw.trp.dao.OrderDao;
import com.trw.trp.dao.OrderDao.ORDER_ACTION;
import com.trw.trp.msg.ResultMessage;
import com.trw.trp.util.ModelUtil;
import com.trw.trp.util.TRPConstants;
import com.trw.trp.util.TRPUtil;
import com.utuan.log.Log;
import com.utuan.log.LogFactory;

public class OrderAction extends AbstractAction {

	private static Log log = LogFactory.getLog(OrderAction.class);

	private String orderId;
	private String isApprove;
	private String period;
	private String start;
	private String limit;
	private String searchType;
	private String userId;
	private String orderNumber;

	private String customerName;
	private String projectName;
	private String productName;
	private String projectNum;

	public String getCustomerName() {
		return customerName;
	}

	public void setCustomerName(String customerName) {
		this.customerName = customerName;
	}

	public String getProjectName() {
		return projectName;
	}

	public void setProjectName(String projectName) {
		this.projectName = projectName;
	}

	public String getProductName() {
		return productName;
	}

	public void setProductName(String productName) {
		this.productName = productName;
	}

	public String getProjectNum() {
		return projectNum;
	}

	public void setProjectNum(String projectNum) {
		this.projectNum = projectNum;
	}

	public String getOrderId() {
		return orderId;
	}

	public void setOrderId(String orderId) {
		this.orderId = orderId;
	}

	public String getIsApprove() {
		return isApprove;
	}

	public void setIsApprove(String isApprove) {
		this.isApprove = isApprove;
	}

	public String getPeriod() {
		return period;
	}

	public void setPeriod(String period) {
		this.period = period;
	}

	public String getStart() {
		return start;
	}

	public void setStart(String start) {
		this.start = start;
	}

	public String getLimit() {
		return limit;
	}

	public void setLimit(String limit) {
		this.limit = limit;
	}

	public String getSearchType() {
		return searchType;
	}

	public void setSearchType(String searchType) {
		this.searchType = searchType;
	}

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public String getOrderNumber() {
		return orderNumber;
	}

	public void setOrderNumber(String orderNumber) {
		this.orderNumber = orderNumber;
	}

	public void searchByMulti() throws IOException {
		OrderDao dao = DaoFactory.getOrderDao();
		SearchCriteriaBean criteria = new SearchCriteriaBean();
		if (this.customerName != null) {
			criteria.setCustomer(customerName);
		}
		if (this.projectName != null) {
			criteria.setProject(projectName);
		}
		if (this.productName != null) {
			criteria.setProduct(this.productName);
		}
		if (this.projectNum != null) {
			criteria.setProjectNum(projectNum);
		}
		List<OrderBean> beans = dao.getOrdersByMulti(criteria);
		int start = 0;
		int limit = 20;
		try {
			start = Integer.parseInt(this.start);
		} catch (Exception e) {
		}
		try {
			limit = Integer.parseInt(this.limit);
		} catch (Exception e) {
		}
		if (beans != null && !beans.isEmpty()) {
			for (OrderBean order : beans) {
				order.generateOrderStatusName();
			}
		}
		writeJSON(beans, start, limit);
	}

	public void getOrdersNeedApprove() throws IOException {
		UserBean user = (UserBean) TRPUtil
				.getFromSession(TRPConstants.CURRENT_USER);
		List<OrderBean> orderList = null;
		OrderDao dao = DaoFactory.getOrderDao();
		SearchCriteriaBean criteria = new SearchCriteriaBean();
		criteria.setTeUserId(user.getUserId());
		criteria.setMinStatus(100);
		orderList = dao.getOrders(criteria);
		if (orderList != null && !orderList.isEmpty()) {
			for (OrderBean order : orderList) {
				order.generateOrderStatusName();
			}
		}
		writeJSON(orderList);
	}

	public void deleteOrder() throws IOException {
		String orderIdStr = getParamFromRequest("orderId");
		ResultMessage ret = new ResultMessage();
		ret.setState(ResultMessage.FAILED);
		long orderId = -1;
		try {
			orderId = Long.parseLong(orderIdStr);
		} catch (NumberFormatException e) {
			ret.setMessage("invalid orderId:" + orderIdStr);
			log.warn(e);
		}
		if (orderId > -1) {
			OrderDao dao = DaoFactory.getOrderDao();
			boolean result = dao.deleteOrder(orderId);
			if (result) {
				ret.setMessage("request deleted.");
				ret.setState(ResultMessage.SUCCESS);
			} else {
				ret.setMessage("request deleted failed,please try again.");
			}
		}
		writeJSON(ret);
	}

	public void getOrders() throws IOException {
		OrderDao dao = DaoFactory.getOrderDao();
		SearchCriteriaBean criteria = new SearchCriteriaBean();
		if (this.userId != null) {
			long userId = -1;
			try {
				userId = Integer.parseInt(this.userId);
			} catch (Exception e) {
			}
			if (userId > -1) {
				criteria.setUserId(userId);
			}
		}
		Calendar cal = new GregorianCalendar();
		cal.setTime(new java.util.Date());
		cal.add(Calendar.MONTH, -3);
		if ("1".equals(period)) {
			criteria.setEndTime(cal.getTime());
		} else if ("0".equals(period)) {
			criteria.setStartTime(cal.getTime());
		}
		if (searchType != null) {
			SearchCriteriaBean.SearchType searchType = SearchCriteriaBean.SearchType
					.valueOf(SearchCriteriaBean.SearchType.class,
							this.searchType);
			if (searchType != null) {
				criteria.setSearchType(searchType);
			}
		}
		criteria.setOrderNumber(orderId);
		try {
			String teUserIdStr = getParamFromRequest("teUserId");
			long teUserId = Long.parseLong(teUserIdStr);
			criteria.setTeUserId(teUserId);
		} catch (Exception e) {
		}

		List<OrderBean> orderList = dao.getOrders(criteria);
		String prjName = StringUtils
				.trimToEmpty(getParamFromRequest("prjName")).toUpperCase();
		if (orderList != null && !orderList.isEmpty()) {
			if (prjName.isEmpty()) {
				for (OrderBean order : orderList) {
					order.generateOrderStatusName();
				}
			} else {
				List<OrderBean> newOrderList = new ArrayList<OrderBean>();
				for (OrderBean order : orderList) {
					if (order.getPrjName().toUpperCase().contains(prjName)) {
						order.generateOrderStatusName();
						newOrderList.add(order);
					}
				}
				orderList = newOrderList;
			}
		}
		int start = 0;
		int limit = 20;
		try {
			start = Integer.parseInt(this.start);
		} catch (Exception e) {
		}
		try {
			limit = Integer.parseInt(this.limit);
		} catch (Exception e) {
		}
		writeJSON(orderList, start, limit);
	}

	public String getOrder() {
		OrderDao dao = DaoFactory.getOrderDao();
		long oNumber = -1;
		if (orderId != null) {
			try {
				oNumber = Long.parseLong(orderId);
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}
		if (oNumber > -1) {
			OrderBean order = dao.getOrder(oNumber);
			TRPUtil.putToSession(TRPConstants.CURRENT_ORDER, order);
		}
		return SUCCESS;
	}

	public void searchByNo() throws IOException {
		OrderDao dao = DaoFactory.getOrderDao();
		OrderBean order = dao.getOrder(orderNumber);
		Map<String, String> json = new HashMap<String, String>();
		json.put("orderId", (order == null ? "" : String.valueOf(order
				.getOrderId())));
		writeJSON(json);
	}

	public String editOrder() throws CloneNotSupportedException {
		int status = -1;
		OrderBean order = null;
		OrderDao dao = DaoFactory.getOrderDao();
		ModelDao modelDao = DaoFactory.getModelDao();
		long oNumber = -1;
		if (orderId != null) {
			oNumber = Long.parseLong(orderId);
		}
		if (oNumber > -1) {
			order = dao.getOrder(oNumber);
			status = order.getStatus() < 0 ? 0 : order.getStatus();
			TRPUtil.putToSession(TRPConstants.CURRENT_ORDER, order);
			TRPUtil.putToSession(TRPConstants.CURRENT_MODEL_STATUS, status);
			List<ModelBean> modelList = new ArrayList<ModelBean>();
			String selectedModels = order.getSelectedModels();
			if (selectedModels != null) {
				String[] modelIdArray = selectedModels
						.split(TRPConstants.COMMA);
				for (String modelIdStr : modelIdArray) {
					try {
						if (!StringUtils.isEmpty(modelIdStr)) {
							ModelBean model = modelDao.getModelById(Long
									.parseLong(modelIdStr.trim()));
							if (model != null) {
								modelList.add(model);
							}
						}
					} catch (NumberFormatException e) {
						log.warn(e);
					}
				}
			}
			TRPUtil.putToSession("modelList", modelList);
		}
		return String.valueOf(status);
	}

	public String nextStatus() throws CloneNotSupportedException {
		OrderBean order = (OrderBean) TRPUtil
				.getFromSession(TRPConstants.CURRENT_ORDER);
		int nextStatus = 2;
		TRPUtil.putToSession(TRPConstants.CURRENT_MODEL_STATUS, nextStatus);
		TRPUtil.putToSession(TRPConstants.CURRENT_MODEL_IDX, 0);
		ModelDao modelDao = DaoFactory.getModelDao();
		List<ModelBean> modelList = modelDao.getModels(nextStatus);
		List<ModelBean> step1ModelList = order.getModelMap().get(1);
		boolean skipMatrix = true;
		if (modelList != null && step1ModelList != null) {
			List<ModelBean> step2ModelList = new ArrayList<ModelBean>();
			List<ModelDetail> step2DetailList = new ArrayList<ModelDetail>();
			for (ModelBean model : step1ModelList) {
				if (model.getModelId() != 13 && model.getModelId() != 14) {
					skipMatrix = false;
				}
				for (ModelBean model2 : modelList) {
					// hard code here
					// if IRS deployment
					if (model.getModelId() == 12 && model2.getModelId() == 4) {
						try {
							ModelBean m = (ModelBean) model2.clone();
							m.setClientUniqueId(model.getClientUniqueId());
							step2ModelList.add(m);
						} catch (CloneNotSupportedException e) {
							log.warn(e);
						}
						step2DetailList.add(modelDao.getModelDetail(model2
								.getModelId()));
						break;
					}
				}
			}
			order.getModelMap().put(nextStatus, step2ModelList);
			order.getDetailMap().put(nextStatus, step2DetailList);
			// generate sampleInfo
			generateSampleInfo(order);
			viewMatrix();
		}
		TRPUtil.putToSession(TRPConstants.CURRENT_ORDER, order);
		if (skipMatrix) {
			return SKIP_MATRIX;
		}
		return SUCCESS;
	}

	public void saveMatrix() throws IOException {
		OrderBean order = (OrderBean) TRPUtil
				.getFromSession(TRPConstants.CURRENT_ORDER);
		List<ModelBean> modelList = order.getModelMap().get(1);
		for (int i = 0; i < modelList.size(); i++) {
			ModelBean model = modelList.get(i);
			if (model.getModelId() == 12) {
				List<OrderBean.MatrixInfo> matrixInfoList = order
						.getMatrixInfoList();
				if (matrixInfoList != null && !matrixInfoList.isEmpty()) {
					OrderBean.MatrixInfo matrixInfo = null;
					for (OrderBean.MatrixInfo matrixInfo0 : matrixInfoList) {
						if (model.getClientUniqueId().equals(
								matrixInfo0.getClientUniqueId())) {
							matrixInfo = matrixInfo0;
							break;
						}
					}
					if (matrixInfo == null) {
						continue;
					}
					for (int j = 0; j < matrixInfo.getFieldList().size(); j++) {
						List<ModelDetail.Field> record = matrixInfo
								.getFieldList().get(j);
						for (ModelDetail.Field field : record) {
							field.setSelectedValue(getFieldValue(field, i, j));
						}
					}
				}
			} else if (model.getModelId() == 20 || model.getModelId() == 21
					|| model.getModelId() == 22) {
			}
		}

		OrderDao dao = DaoFactory.getOrderDao();
		dao.saveOrder(order, 2);
		dao.saveOrder(order, 3);
	}

	public void transferOrder() throws IOException {
		boolean result = true;
		OrderBean order = (OrderBean) TRPUtil
				.getFromSession(TRPConstants.CURRENT_ORDER);
		String newTeUserId = getParamFromRequest("newTeUserId");
		String fixtureArr = getParamFromRequest("fixtureStr");
		String sampleArr = getParamFromRequest("sampleStr");
		UserBean user = (UserBean) TRPUtil
				.getFromSession(TRPConstants.CURRENT_USER);
		String comment = getParamFromRequest("comment");
		try {
			OrderDao dao = DaoFactory.getOrderDao();
			result = dao.transferOrder(order, Long.parseLong(newTeUserId), user
					.getUserId(), sampleArr, fixtureArr, comment);
			if (result) {
				String url = generateViewOrderUrl(order);
				String orderNumber = order.getOrderNumber();
				String projectName = generateProjectName(order);
				generateEmail(new Object[] { orderNumber, projectName,
						user.getName(), url });
			}
		} catch (Exception e) {
			log.warn(e);
			result = false;
		}
		ResultMessage ret = new ResultMessage();
		ret.setState(result ? ResultMessage.SUCCESS : ResultMessage.FAILED);
		writeJSON(ret);
	}

	private String getFieldValue(ModelDetail.Field field, int idx, int recordIdx) {
		StringBuilder value = new StringBuilder();
		value.append(trimValue(getParamFromRequest("p_" + idx + "_" + recordIdx
				+ "_" + field.getFieldId())));
		return value.toString();
	}

	public void getMatrix() throws IOException {
		log.info("Generating matrix...");
		OrderBean order = (OrderBean) TRPUtil
				.getFromSession(TRPConstants.CURRENT_ORDER);
		String idxStr = getParamFromRequest("idx");
		int idx = -1;
		try {
			idx = Integer.parseInt(idxStr);
		} catch (Exception e) {

		}
		writeJSON(getMatrix0(order, idx));
		log.info("Generating matrix done, go to viewMatrix page...");
	}

	public void getSpareParts() throws IOException {
		OrderBean order = (OrderBean) TRPUtil
				.getFromSession(TRPConstants.CURRENT_ORDER);
		String idxStr = getParamFromRequest("idx");
		int idx = -1;
		try {
			idx = Integer.parseInt(idxStr);
		} catch (Exception e) {

		}
		writeJSON(getSpareParts0(order, idx));
	}

	private List<Map<String, String>> getSpareParts0(OrderBean order, int idx) {
		List<Map<String, String>> ret = new ArrayList<Map<String, String>>();
		List<ModelDetail> detailList = order.getDetailMap().get(1);
		List<ModelBean> modelList = order.getModelMap().get(1);
		ModelDetail detail = detailList.get(idx);
		ModelBean model = modelList.get(idx);
		if (model.getModelId() == 12) {
			int[][] marginArray = new int[9][3];
			String side = null;
			String hrlT = null;
			String[] inflatorTypes2 = { "High Margin", "Nominal", "Low Margin" };
			Map<Long, ModelDetail.Field> detailMap = new HashMap<Long, ModelDetail.Field>();
			for (ModelDetail.ModelSection section : detail.getSectionList()) {
				for (ModelDetail.Field field : section.getFieldList()) {
					detailMap.put(field.getFieldId(), field);
					if (field.getFieldId() == 384) {
						try {
							marginArray[0][0] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 385) {
						try {
							marginArray[0][1] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 386) {
						try {
							marginArray[0][2] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 387) {
						try {
							marginArray[1][0] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 388) {
						try {
							marginArray[1][1] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 389) {
						try {
							marginArray[1][2] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 390) {
						try {
							marginArray[2][0] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 391) {
						try {
							marginArray[2][1] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 392) {
						try {
							marginArray[2][2] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 399) {
						try {
							marginArray[3][0] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 400) {
						try {
							marginArray[3][1] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 401) {
						try {
							marginArray[3][2] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 402) {
						try {
							marginArray[4][0] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 403) {
						try {
							marginArray[4][1] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 404) {
						try {
							marginArray[4][2] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 405) {
						try {
							marginArray[5][0] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 406) {
						try {
							marginArray[5][1] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 407) {
						try {
							marginArray[5][2] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 414) {
						try {
							marginArray[6][0] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 415) {
						try {
							marginArray[6][1] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 416) {
						try {
							marginArray[6][2] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 417) {
						try {
							marginArray[7][0] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 418) {
						try {
							marginArray[7][1] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 419) {
						try {
							marginArray[7][2] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 420) {
						try {
							marginArray[8][0] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 421) {
						try {
							marginArray[8][1] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					} else if (field.getFieldId() == 422) {
						try {
							marginArray[8][2] = Integer.parseInt(field
									.getSelectedValue());
						} catch (Exception e) {
						}
					}
				}
			}

			String ignitionCurrent = new StringBuilder(detailMap.get(55L)
					.getSelectedValue()).append("(").append(
					detailMap.get(57L).getSelectedValue()).append(" ~ ")
					.append(detailMap.get(56L).getSelectedValue()).append(")")
					.toString();
			String ignitionCurrentDuration = new StringBuilder(detailMap.get(
					59L).getSelectedValue()).append("(").append(
					detailMap.get(61L).getSelectedValue()).append(" ~ ")
					.append(detailMap.get(60L).getSelectedValue()).append(")")
					.toString();
			String ignitionResistance = new StringBuilder(detailMap.get(51L)
					.getSelectedValue()).append("(").append(
					detailMap.get(53L).getSelectedValue()).append(" ~ ")
					.append(detailMap.get(52L).getSelectedValue()).append(")")
					.toString();
			String timeFromRemovalToIgnition = new StringBuilder(detailMap.get(
					39L).getSelectedValue()).append("(").append(
					detailMap.get(41L).getSelectedValue()).append(" ~ ")
					.append(detailMap.get(40L).getSelectedValue()).append(")")
					.toString();
			String restorageTime = new StringBuilder(detailMap.get(43L)
					.getSelectedValue()).append("(").append(
					detailMap.get(45L).getSelectedValue()).append(" ~ ")
					.append(detailMap.get(44L).getSelectedValue()).append(")")
					.toString();
			String moduleMountingTime = new StringBuilder(detailMap.get(47L)
					.getSelectedValue()).append("(").append(
					detailMap.get(49L).getSelectedValue()).append(" ~ ")
					.append(detailMap.get(48L).getSelectedValue()).append(")")
					.toString();

			int rowNumber = 0;
			for (int j = 0; j < marginArray.length; j++) {
				String inflatorType2 = inflatorTypes2[j / 3];
				int[] marginItem = marginArray[j];
				for (int k = 0; k < marginItem[0]; k++, rowNumber++) {
					if (k < marginItem[1]) {
						side = "left";
					} else if (k < marginItem[1] + marginItem[2]) {
						side = "right";
					} else {
						side = "";
					}
					if (j % 3 == 0) {
						hrlT = "HT";
					} else if (j % 3 == 1) {
						hrlT = "RT";
					} else {
						hrlT = "LT";
					}
					Map<String, String> record = new HashMap<String, String>();
					ret.add(record);
					record.put("idx", String.valueOf(rowNumber));
					record.put("testTemp", hrlT);
					record.put("inflatorType", inflatorType2);
					record.put("side", side);
					record.put("ignitionC", ignitionCurrent);
					record.put("ignitionCD", ignitionCurrentDuration);
					record.put("ignitionR", ignitionResistance);
					record.put("timeFRTI", timeFromRemovalToIgnition);
					record.put("restorageTime", restorageTime);
					record.put("moduleMountingTime", moduleMountingTime);
					if ("HT".equals(hrlT)) {
						record.put("storageTemp", new StringBuilder(detailMap
								.get(3L).getSelectedValue()).append("(")
								.append(detailMap.get(5L).getSelectedValue())
								.append(" ~ ").append(
										detailMap.get(4L).getSelectedValue())
								.append(")").toString());// storage
						// temp.
						record
								.put("min", detailMap.get(17L)
										.getSelectedValue());// min.
						record
								.put("max", detailMap.get(16L)
										.getSelectedValue());// max.
						record.put("testTemperature", new StringBuilder(
								detailMap.get(26L).getSelectedValue()).append(
								"(").append(
								detailMap.get(28L).getSelectedValue()).append(
								" ~ ").append(
								detailMap.get(27L).getSelectedValue()).append(
								")").toString());// test
						// temp.
					} else if ("RT".equals(hrlT)) {
						record.put("storageTemp", new StringBuilder(detailMap
								.get(7L).getSelectedValue()).append("(")
								.append(detailMap.get(9L).getSelectedValue())
								.append(" ~ ").append(
										detailMap.get(8L).getSelectedValue())
								.append(")").toString());// storage
						// temp.
						record
								.put("min", detailMap.get(20L)
										.getSelectedValue());// min.
						record
								.put("max", detailMap.get(19L)
										.getSelectedValue());// max.
						record.put("testTemperature", new StringBuilder(
								detailMap.get(30L).getSelectedValue()).append(
								"(").append(
								detailMap.get(32L).getSelectedValue()).append(
								" ~ ").append(
								detailMap.get(31L).getSelectedValue()).append(
								")").toString());// test
						// temp.
					} else if ("LT".equals(hrlT)) {
						record.put("storageTemp", new StringBuilder(detailMap
								.get(11L).getSelectedValue()).append("(")
								.append(detailMap.get(13L).getSelectedValue())
								.append(" ~ ").append(
										detailMap.get(12L).getSelectedValue())
								.append(")").toString());// storage
						// temp.
						record
								.put("min", detailMap.get(23L)
										.getSelectedValue());// min.
						record
								.put("max", detailMap.get(22L)
										.getSelectedValue());// max.
						record.put("testTemperature", new StringBuilder(
								detailMap.get(34L).getSelectedValue()).append(
								"(").append(
								detailMap.get(36L).getSelectedValue()).append(
								" ~ ").append(
								detailMap.get(35L).getSelectedValue()).append(
								")").toString());// test
						// temp.
					}
				}
			}

		}
		return ret;
	}

	private List<Map<String, String>> getMatrix0(OrderBean order, int idx) {
		List<Map<String, String>> matrix = new ArrayList<Map<String, String>>();
		if (idx > -1) {
			List<OrderBean.SampleInfo> smapleInfoList = order
					.getSampleInfoList();
			List<OrderBean.MatrixInfo> matrixInfoList = order
					.getMatrixInfoList();
			List<ModelDetail> detailList = order.getDetailMap().get(1);
			List<ModelBean> modelList = order.getModelMap().get(1);
			ModelDetail detail = detailList.get(idx);
			ModelBean model = modelList.get(idx);
			if (model.getModelId() == 12) {
				OrderBean.SampleInfo sampleInfo = null;
				if (smapleInfoList != null) {
					for (OrderBean.SampleInfo sampleInfo0 : smapleInfoList) {
						if (model.getClientUniqueId().equals(
								sampleInfo0.getClientUniqueId())) {
							sampleInfo = sampleInfo0;
							break;
						}
					}
				}
				OrderBean.MatrixInfo matrixInfo = null;
				if (matrixInfoList != null) {
					for (OrderBean.MatrixInfo matrixInfo0 : matrixInfoList) {
						if (model.getClientUniqueId().equals(
								matrixInfo0.getClientUniqueId())) {
							matrixInfo = matrixInfo0;
							break;
						}
					}
				}
				if (sampleInfo == null || matrixInfo == null) {
					return matrix;
				}

				Map<String, String> record = null;
				Map<Long, ModelDetail.Field> detailMap = new HashMap<Long, ModelDetail.Field>();
				for (ModelDetail.ModelSection section : detail.getSectionList()) {
					for (ModelDetail.Field field : section.getFieldList()) {
						detailMap.put(field.getFieldId(), field);
					}
				}
				for (List<ModelDetail.Field> matrixRecord : matrixInfo
						.getFieldList()) {
					int index = Integer.parseInt(matrixRecord.get(0)
							.getSelectedValue());
					List<ModelDetail.Field> fields = sampleInfo
							.getFieldListMap().get(5L).get(index);
					Map<Long, ModelDetail.Field> tempMap = new HashMap<Long, ModelDetail.Field>();
					for (ModelDetail.Field field : fields) {
						tempMap.put(field.getFieldId(), field);
					}
					record = new HashMap<String, String>();
					matrix.add(record);
					record.put("idx", String.valueOf(index));
					record
							.put("testTemp", tempMap.get(152L)
									.getSelectedValue());// Test
					// Temp.
					record.put("side", tempMap.get(151L).getSelectedValue());// left/right.
					record.put("inflatorType", tempMap.get(153L)
							.getSelectedValue());// inflator
					// type.
					record.put("ignitionC", new StringBuilder(detailMap
							.get(55L).getSelectedValue()).append("(").append(
							detailMap.get(57L).getSelectedValue())
							.append(" ~ ").append(
									detailMap.get(56L).getSelectedValue())
							.append(")").toString());// ignition
					// current.
					record.put("ignitionCD", new StringBuilder(detailMap.get(
							59L).getSelectedValue()).append("(").append(
							detailMap.get(61L).getSelectedValue())
							.append(" ~ ").append(
									detailMap.get(60L).getSelectedValue())
							.append(")").toString());// ignition
					// current
					// duration.
					record.put("ignitionR", new StringBuilder(detailMap
							.get(51L).getSelectedValue()).append("(").append(
							detailMap.get(53L).getSelectedValue())
							.append(" ~ ").append(
									detailMap.get(52L).getSelectedValue())
							.append(")").toString());// ignition
					// resistance.
					record.put("timeFRTI", new StringBuilder(detailMap.get(39L)
							.getSelectedValue()).append("(").append(
							detailMap.get(41L).getSelectedValue())
							.append(" ~ ").append(
									detailMap.get(40L).getSelectedValue())
							.append(")").toString());// time
					// from
					// remove
					// to
					// //
					// ignition.
					if ("HT".equals(tempMap.get(152L).getSelectedValue())) {
						record.put("storageTemp", new StringBuilder(detailMap
								.get(3L).getSelectedValue()).append("(")
								.append(detailMap.get(5L).getSelectedValue())
								.append(" ~ ").append(
										detailMap.get(4L).getSelectedValue())
								.append(")").toString());// storage
						// temp.
						record
								.put("min", detailMap.get(17L)
										.getSelectedValue());// min.
						record
								.put("max", detailMap.get(16L)
										.getSelectedValue());// max.
						record.put("testTemperature", new StringBuilder(
								detailMap.get(26L).getSelectedValue()).append(
								"(").append(
								detailMap.get(28L).getSelectedValue()).append(
								" ~ ").append(
								detailMap.get(27L).getSelectedValue()).append(
								")").toString());// test
						// temp.
					} else if ("RT"
							.equals(tempMap.get(152L).getSelectedValue())) {
						record.put("storageTemp", new StringBuilder(detailMap
								.get(7L).getSelectedValue()).append("(")
								.append(detailMap.get(9L).getSelectedValue())
								.append(" ~ ").append(
										detailMap.get(8L).getSelectedValue())
								.append(")").toString());// storage
						// temp.
						record
								.put("min", detailMap.get(20L)
										.getSelectedValue());// min.
						record
								.put("max", detailMap.get(19L)
										.getSelectedValue());// max.
						record.put("testTemperature", new StringBuilder(
								detailMap.get(30L).getSelectedValue()).append(
								"(").append(
								detailMap.get(32L).getSelectedValue()).append(
								" ~ ").append(
								detailMap.get(31L).getSelectedValue()).append(
								")").toString());// test
						// temp.
					} else if ("LT"
							.equals(tempMap.get(152L).getSelectedValue())) {
						record.put("storageTemp", new StringBuilder(detailMap
								.get(11L).getSelectedValue()).append("(")
								.append(detailMap.get(13L).getSelectedValue())
								.append(" ~ ").append(
										detailMap.get(12L).getSelectedValue())
								.append(")").toString());// storage
						// temp.
						record
								.put("min", detailMap.get(23L)
										.getSelectedValue());// min.
						record
								.put("max", detailMap.get(22L)
										.getSelectedValue());// max.
						record.put("testTemperature", new StringBuilder(
								detailMap.get(34L).getSelectedValue()).append(
								"(").append(
								detailMap.get(36L).getSelectedValue()).append(
								" ~ ").append(
								detailMap.get(35L).getSelectedValue()).append(
								")").toString());// test
						// temp.
					}
					record.put("restorageTime", new StringBuilder(detailMap
							.get(43L).getSelectedValue()).append("(").append(
							detailMap.get(45L).getSelectedValue())
							.append(" ~ ").append(
									detailMap.get(44L).getSelectedValue())
							.append(")").toString());// restorage
					// time.
					record.put("moduleMountingTime", new StringBuilder(
							detailMap.get(47L).getSelectedValue()).append("(")
							.append(detailMap.get(49L).getSelectedValue())
							.append(" ~ ").append(
									detailMap.get(48L).getSelectedValue())
							.append(")").toString());// module
					// mounting
					// time.
				}
			} else if (model.getModelId() == 20 || model.getModelId() == 21
					|| model.getModelId() == 22 || model.getModelId() == 23) {
				Map<Long, ModelDetail.Field> fieldMap = new HashMap<Long, ModelDetail.Field>();
				for (ModelDetail.ModelSection section : detail.getSectionList()) {
					for (ModelDetail.Field field : section.getFieldList()) {
						fieldMap.put(field.getFieldId(), field);
					}
				}
				long[] fieldIds = null;
				String[] indices = null;
				if (model.getModelId() == 20) {
					fieldIds = new long[] { 227L, 228L, 231L, 232L, 270L, 271L,
							229L, 230L, 235L, 236L, 233L, 340L };
					indices = new String[] { "ignitionC", "currentDur",
							"framePerSec", "videoRecTime", "temp",
							"storageTime", "dualStageInflator", "stageD",
							"length", "width", "impactMass", "Velocity",
							"TestQuantity", "Position", "Temperature",
							"ModuleParameter" };
				} else if (model.getModelId() == 21) {
					fieldIds = new long[] { 211L, 212L, 215L, 216L, 284L, 285L,
							213L, 214L, 217L, 261L };
					indices = new String[] { "ignitionC", "currentDur",
							"framePerSec", "videoRecTime", "temp",
							"storageTime", "dualStageInflator", "stageD",
							"impactType", "Velocity", "TestQuantity",
							"Position", "Temperature", "ModuleParameter" };
				} else if (model.getModelId() == 22) {
					fieldIds = new long[] { 169L, 170L, 173L, 174L, 296L, 297L,
							171L, 172L, 175L, 178L, 191L };
					indices = new String[] { "ignitionC", "currentDur",
							"framePerSec", "videoRecTime", "temp",
							"storageTime", "dualStageInflator", "stageD",
							"impactMass", "columnAngle", "Velocity",
							"TestQuantity", "Position", "Temperature",
							"ModuleParameter" };
				} else if (model.getModelId() == 23) {
					// fieldIds = new long[12];
					fieldIds = new long[] { 311L, 312L, 313L, 314L, 315L, 316L,
							317L, 318L, 320L, 321L, 322L, 335L };
					indices = new String[] { "ignitionC", "currentDur",
							"framePerSec", "videoRecTime", "temp",
							"storageTime", "dualStageInflator", "stageD",
							"length", "width", "impactMass", "PushDistance",
							"TestQuantity", "Position", "Temperature",
							"ModuleParameter" };
				}
				List<JSONObject> testMatrix = ModelUtil.parseMatrix(fieldMap
						.get(fieldIds[fieldIds.length - 1]));
				Map<String, String> record;
				ModelDetail.Field field0;
				for (int i = 0; i < testMatrix.size(); i++) {
					JSONObject jsonObj = testMatrix.get(i);
					record = new HashMap<String, String>();
					matrix.add(record);
					for (int j = 0; j < fieldIds.length; j++) {
						field0 = fieldMap.get(fieldIds[j]);
						if (field0.getFieldType() == 33) {
							for (int k = j; k < indices.length; k++) {
								record.put(indices[k], jsonObj
										.getString(indices[k]));
							}
						} else {
							record.put(indices[j], field0.getSelectedValue());
						}
					}
					int quantity = 0;
					try {
						quantity = Integer.parseInt(record.get("TestQuantity"));
					} catch (NumberFormatException nfe) {
						log.warn(nfe);
					}
					if (quantity > 1) {
						record.put("TestQuantity", "1");
						Map<String, String> addRecord;
						for (int m = 0; m < quantity - 1; m++) {
							addRecord = new HashMap<String, String>();
							matrix.add(addRecord);
							for (Map.Entry<String, String> entry : record
									.entrySet()) {
								addRecord.put(entry.getKey(), entry.getValue());
							}
						}
					}
				}
			}
		}
		return matrix;
	}

	private void generateSampleInfo(OrderBean order)
			throws CloneNotSupportedException {
		List<ModelBean> step1ModelList = order.getModelMap().get(1);
		List<ModelDetail> step1DetailList = order.getDetailMap().get(1);
		List<ModelBean> step2ModelList = order.getModelMap().get(2);
		List<ModelDetail> step2DetailList = order.getDetailMap().get(2);
		List<OrderBean.SampleInfo> oldSampleInfoList = order
				.getSampleInfoList();
		List<OrderBean.SampleInfo> sampleInfoList = new ArrayList<OrderBean.SampleInfo>();
		for (int i = 0; i < step2ModelList.size(); i++) {
			ModelBean model = null;
			ModelBean model2 = step2ModelList.get(i);
			ModelDetail detail2 = step2DetailList.get(i);
			ModelDetail detail = null;
			for (int j = 0; j < step1ModelList.size(); j++) {
				if (model2.getClientUniqueId().equals(
						step1ModelList.get(j).getClientUniqueId())) {
					model = step1ModelList.get(j);
					detail = step1DetailList.get(j);
					break;
				}
			}
			OrderBean.SampleInfo sampleInfo = null;

			if (model2.getModelId() == 4) {
				int[][] marginArray = new int[9][3];
				int rowNumber = 1;
				String side = null;
				String hrlT = null;
				String[] inflatorTypes2 = { "High Margin", "Nominal",
						"Low Margin" };
				String sampleDepict = order.getGeneralInfo().getProject() + " "
						+ order.getGeneralInfo().getProduct();
				for (ModelDetail.ModelSection section : detail.getSectionList()) {
					for (ModelDetail.Field field : section.getFieldList()) {
						if (field.getFieldId() == 75) {
							try {
								marginArray[0][0] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 82) {
							try {
								marginArray[0][1] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 83) {
							try {
								marginArray[0][2] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 76) {
							try {
								marginArray[1][0] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 84) {
							try {
								marginArray[1][1] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 85) {
							try {
								marginArray[1][2] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 77) {
							try {
								marginArray[2][0] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 86) {
							try {
								marginArray[2][1] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 87) {
							try {
								marginArray[2][2] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 91) {
							try {
								marginArray[3][0] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 98) {
							try {
								marginArray[3][1] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 99) {
							try {
								marginArray[3][2] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 92) {
							try {
								marginArray[4][0] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 100) {
							try {
								marginArray[4][1] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 101) {
							try {
								marginArray[4][2] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 93) {
							try {
								marginArray[5][0] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 102) {
							try {
								marginArray[5][1] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 103) {
							try {
								marginArray[5][2] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 107) {
							try {
								marginArray[6][0] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 114) {
							try {
								marginArray[6][1] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 115) {
							try {
								marginArray[6][2] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 108) {
							try {
								marginArray[7][0] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 116) {
							try {
								marginArray[7][1] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 117) {
							try {
								marginArray[7][2] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 109) {
							try {
								marginArray[8][0] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 118) {
							try {
								marginArray[8][1] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						} else if (field.getFieldId() == 119) {
							try {
								marginArray[8][2] = Integer.parseInt(field
										.getSelectedValue());
							} catch (Exception e) {
							}
						}
					}
				}

				// compare whether there are any change for sample info
				if (oldSampleInfoList != null) {
					for (OrderBean.SampleInfo si : oldSampleInfoList) {
						if (si.getClientUniqueId().equals(
								model.getClientUniqueId())) {
							sampleInfo = si;
							break;
						}
					}
				}
				if (sampleInfo != null) {
					int[][] oldIdentities = new int[9][3];
					String orgValue = "HT";
					String orgValue2 = "High Margin";
					int idx = 0;
					List<List<ModelDetail.Field>> recordList = sampleInfo
							.getFieldListMap().get(5L);
					if (recordList != null) {
						for (List<ModelDetail.Field> record : recordList) {
							orgValue = record.get(3).getSelectedValue();
							orgValue2 = record.get(4).getSelectedValue();
							if ("High Margin".equals(orgValue)) {
								idx = 0;
							} else if ("Nomimal".equals(orgValue)) {
								idx = 3;
							} else {
								idx = 6;
							}
							if ("RT".equals(orgValue2)) {
								idx += 1;
							} else if ("LT".equals(orgValue2)) {
								idx += 2;
							}
							oldIdentities[idx][0]++;
							if ("left".equalsIgnoreCase(record.get(2)
									.getSelectedValue())) {
								oldIdentities[idx][1]++;
							} else if ("right".equalsIgnoreCase(record.get(2)
									.getSelectedValue())) {
								oldIdentities[idx][2]++;
							}
						}
					}
					// oldIdentities = trimZeroElement(oldIdentities);
					// marginArray = trimZeroElement(marginArray);
					if (oldIdentities.length == marginArray.length) {
						boolean flag = false;
						for (int ii = 0; ii < oldIdentities.length; ii++) {
							if (oldIdentities[ii].length == 3
									&& marginArray[ii].length == 3) {
								if (!Arrays.equals(oldIdentities[ii],
										marginArray[ii])) {
									flag = true;
								}
							} else {
								flag = true;
							}
							if (flag) {
								break;
							}
						}
						if (flag) {
							sampleInfo = null;
						}
					} else {
						sampleInfo = null;
					}
				}
				if (sampleInfo == null) {
					sampleInfo = new OrderBean.SampleInfo();
					sampleInfo.setClientUniqueId(model.getClientUniqueId());
					sampleInfo
							.setFieldListMap(new HashMap<Long, List<List<ModelDetail.Field>>>());

					List<ModelDetail.ModelSection> sectionList = detail2
							.getSectionList();
					List<ModelDetail.Field> fieldList = null;
					List<List<ModelDetail.Field>> sampleInfoFields = null;
					for (ModelDetail.ModelSection section : sectionList) {
						fieldList = section.getFieldList();
						sampleInfoFields = new ArrayList<List<ModelDetail.Field>>();
						sampleInfo.getFieldListMap().put(section.getId(),
								sampleInfoFields);
						if (section.getId() == 5) {
							for (int j = 0; j < marginArray.length; j++) {
								String inflatorType2 = inflatorTypes2[j / 3];
								int[] marginItem = marginArray[j];
								for (int k = 0; k < marginItem[0]; k++, rowNumber++) {
									if (k < marginItem[1]) {
										side = "left";
									} else if (k < marginItem[1]
											+ marginItem[2]) {
										side = "right";
									} else {
										side = "";
									}
									if (j % 3 == 0) {
										hrlT = "HT";
									} else if (j % 3 == 1) {
										hrlT = "RT";
									} else {
										hrlT = "LT";
									}
									List<ModelDetail.Field> fieldList0 = new ArrayList<ModelDetail.Field>();
									sampleInfoFields.add(fieldList0);
									for (ModelDetail.Field field : fieldList) {
										fieldList0
												.add((ModelDetail.Field) field
														.clone());
									}
									fieldList0.get(0).setSelectedValue(
											String.valueOf(rowNumber));
									fieldList0.get(1).setSelectedValue(
											sampleDepict);
									fieldList0.get(2).setSelectedValue(side);
									fieldList0.get(3).setSelectedValue(hrlT);
									fieldList0.get(4).setSelectedValue(
											inflatorType2);
								}
							}
						} else {
							// TODO: update other sections here
						}
					}
				}
			} else {
				// TODO: update other models here
			}
			if (sampleInfo != null) {
				sampleInfoList.add(sampleInfo);
			}
		}
		order.setSampleInfoList(sampleInfoList);
	}

	public void approveOrder() throws IOException {
		boolean isApproveAction = Boolean.parseBoolean(isApprove);
		UserBean user = (UserBean) TRPUtil
				.getFromSession(TRPConstants.CURRENT_USER);
		OrderDao dao = DaoFactory.getOrderDao();
		long oNumber = -1;
		if (orderId != null) {
			oNumber = Long.parseLong(orderId);
		}
		OrderBean order = dao.getOrder(oNumber);
		int status = order.getStatus();
		String comment = getParamFromRequest("comment");
		String action = null;
		if (isApproveAction) {
			status = order.getInputStatus();
			action = ORDER_ACTION.Approve.toString();
		} else {
			status = -2;
			action = ORDER_ACTION.Reject.toString();
		}
		dao.changeOrderStatus(order, status, action, user, comment);
		Object[] params;
		String projectName = generateProjectName(order);
		if (isApproveAction) {
			HttpServletRequest request = ServletActionContext.getRequest();
			String url = new StringBuffer().append(request.getScheme()).append(
					"://").append(
					java.net.InetAddress.getLocalHost().getHostAddress())
					.append(":").append(request.getServerPort()).append(
							"/trp/editOrder.action?orderId=").append(orderId)
					.toString();
			params = new Object[] { order.getOrderNumber(), projectName,
					user.getName(), url };
		} else {
			params = new Object[] { order.getOrderNumber(), projectName,
					user.getName(), comment };
		}
		generateEmail(params);
		ResultMessage msg = new ResultMessage();
		msg.setState(ResultMessage.SUCCESS);
		if (isApproveAction) {
			msg.setMessage(AppConfiguration.getInstance().getProperty(
					"msg.approve"));
		} else {
			msg.setMessage(AppConfiguration.getInstance().getProperty(
					"msg.reject"));
		}
		writeJSON(msg);
	}

	public void getOrderHistory() throws IOException {
		OrderDao dao = DaoFactory.getOrderDao();
		long oNumber = -1;
		if (orderId != null) {
			oNumber = Long.parseLong(orderId);
		}
		List<OrderHistoryBean> historyList = dao.getHistory(oNumber);
		writeJSON(historyList);
	}

	public void updateTestPartInfo() throws IOException {
		ResultMessage ret = new ResultMessage();
		try {
			OrderBean order = (OrderBean) TRPUtil
					.getFromSession(TRPConstants.CURRENT_ORDER);
			OrderDao dao = DaoFactory.getOrderDao();
			dao.saveOrder(order, 4);
			order.setInputStatus(3);
			TRPUtil.putToSession(TRPConstants.CURRENT_ORDER, order);
		} catch (Exception e) {
			log.warn(e);
			ret.setState(ResultMessage.FAILED);
			ret.setMessage(e.getMessage());
		}
		writeJSON(ret);
	}

	public void sendEmail() throws IOException {
		ResultMessage ret = new ResultMessage();
		try {
			OrderBean order = (OrderBean) TRPUtil
					.getFromSession(TRPConstants.CURRENT_ORDER);
			OrderDao dao = DaoFactory.getOrderDao();
			order = dao.getOrder(order.getOrderId());
			if (order.getStatus() < order.getInputStatus()) {
				int nextStatus = order.getStatus();
				if (nextStatus < 0) {
					nextStatus = 100;
				} else if (nextStatus < 100) {
					nextStatus += 100;
				}
				dao.changeOrderStatus(order, nextStatus, null, null, null);
				order.setStatus(nextStatus);
				TRPUtil.putToSession(TRPConstants.CURRENT_ORDER, order);
			}
			String text = generateViewOrderUrl(order);
			String projectName = generateProjectName(order);
			ret.setMessage(generateEmail(new Object[] { order.getOrderNumber(),
					projectName, order.getUser().getName(), text }));
		} catch (Exception e) {
			log.warn(e);
			ret.setState(ResultMessage.FAILED);
			ret.setMessage(e.getMessage());
		}
		writeJSON(ret);
	}

	private List<Map<String, String>> getSampleInfo0(int idx, long sectionIdx) {
		List<Map<String, String>> records = null;
		try {
			OrderBean order = (OrderBean) TRPUtil
					.getFromSession(TRPConstants.CURRENT_ORDER);
			List<ModelBean> modelList = order.getModelMap().get(1);
			ModelBean model = modelList.get(idx);
			OrderBean.SampleInfo sampleInfo = null;
			if (order.getSampleInfoList() != null) {
				for (OrderBean.SampleInfo sampleInfo0 : order
						.getSampleInfoList()) {
					if (model.getClientUniqueId().equals(
							sampleInfo0.getClientUniqueId())) {
						sampleInfo = sampleInfo0;
						break;
					}
				}
			}
			if (sampleInfo != null) {
				List<List<ModelDetail.Field>> recordList = sampleInfo
						.getFieldListMap().get(sectionIdx);
				records = new ArrayList<Map<String, String>>();
				if (model.getModelId() == 12) {
					if (sectionIdx == 5) {
						if (recordList != null) {
							for (List<ModelDetail.Field> fieldList : recordList) {
								Map<String, String> record = new HashMap<String, String>();
								records.add(record);
								record.put("partName", fieldList.get(1)
										.getSelectedValue());
								record.put("side", fieldList.get(2)
										.getSelectedValue());
								record.put("testTemp", fieldList.get(3)
										.getSelectedValue());
								record.put("inflatorType", fieldList.get(4)
										.getSelectedValue());
							}
						}
					}
				}
			} else {
				// other models goes here.
			}
		} catch (Exception e) {
			log.warn(e);
		}
		return records;
	}

	public void getSampleInfo() throws IOException {
		int idx = -1;
		long sectionIdx = -1;
		List<Map<String, String>> records = null;
		try {
			idx = Integer.parseInt(getParamFromRequest("idx"));
			sectionIdx = Long.parseLong(getParamFromRequest("sectionIdx"));
			records = getSampleInfo0(idx, sectionIdx);
		} catch (NumberFormatException e) {
			log.warn(e);
		}
		if (records == null) {
			records = Collections.emptyList();
		}
		writeJSON(records);
	}

	/*
	 * public void getSampleInfo() throws CloneNotSupportedException,
	 * IOException { int idx = -1; long sectionIdx = -1; List<Map<String,
	 * String>> records = null; try { idx =
	 * Integer.parseInt(getParamFromRequest("idx")); sectionIdx =
	 * Long.parseLong(getParamFromRequest("sectionIdx")); OrderBean order =
	 * (OrderBean) TRPUtil .getFromSession(TRPConstants.CURRENT_ORDER);
	 * List<ModelBean> modelList = order.getModelMap().get(1);
	 * OrderBean.SampleInfo sampleInfo = null; if (order.getSampleInfoList() !=
	 * null && order.getSampleInfoList().size() > idx) { sampleInfo =
	 * order.getSampleInfoList().get(idx); } ModelBean model =
	 * modelList.get(idx); if (sampleInfo != null) {
	 * List<List<ModelDetail.Field>> recordList = sampleInfo
	 * .getFieldListMap().get(sectionIdx); records = new ArrayList<Map<String,
	 * String>>(); if (model.getModelId() == 12) { if (sectionIdx == 7) { if
	 * (recordList != null) { for (List<ModelDetail.Field> fieldList :
	 * recordList) { Map<String, String> record = new HashMap<String, String>();
	 * records.add(record); record.put("amount", fieldList.get(1)
	 * .getSelectedValue()); record.put("partName", fieldList.get(2)
	 * .getSelectedValue()); record.put("partNumber", fieldList.get(3)
	 * .getSelectedValue()); record.put("desc", fieldList.get(4)
	 * .getSelectedValue()); record.put("purpose", fieldList.get(5)
	 * .getSelectedValue()); record.put("remark", fieldList.get(6)
	 * .getSelectedValue()); record.put("labBarcode", fieldList.get(7)
	 * .getSelectedValue()); } } } else if (sectionIdx == 5) { for
	 * (List<ModelDetail.Field> fieldList : recordList) { Map<String, String>
	 * record = new HashMap<String, String>(); records.add(record); int i = 1;
	 * record.put("HRLT", fieldList.get(i++) .getSelectedValue());
	 * record.put("partName", fieldList.get(i++) .getSelectedValue());
	 * record.put("side", fieldList.get(i++) .getSelectedValue());
	 * record.put("inflatorType1", fieldList.get(i++) .getSelectedValue());
	 * record.put("inflatorType2", fieldList.get(i++) .getSelectedValue());
	 * record.put("afterES", fieldList.get(i++) .getSelectedValue());
	 * record.put("purpose", fieldList.get(i++) .getSelectedValue());
	 * record.put("labBarcode", fieldList.get(i++) .getSelectedValue());
	 * record.put("cMaterial", fieldList.get(i++) .getSelectedValue());
	 * record.put("foldingType", fieldList.get(i++) .getSelectedValue());
	 * record.put("circle", fieldList.get(i++) .getSelectedValue());
	 * record.put("slotLength", fieldList.get(i++) .getSelectedValue());
	 * record.put("others", fieldList.get(i++) .getSelectedValue());
	 * record.put("mSerialNumber", fieldList.get(i++) .getSelectedValue());
	 * record.put("iSerialNumber", fieldList.get(i++) .getSelectedValue());
	 * record.put("remark", fieldList.get(i++) .getSelectedValue()); } } } } }
	 * catch (NumberFormatException e) { log.warn(e); } if (records == null) {
	 * records = Collections.emptyList(); } writeJSON(records); }
	 */

	public void updateSampleInfo() throws IOException,
			CloneNotSupportedException {
		OrderDao dao = DaoFactory.getOrderDao();
		OrderBean order = (OrderBean) TRPUtil
				.getFromSession(TRPConstants.CURRENT_ORDER);
		List<OrderBean.SampleInfo> sampleInfoList = order.getSampleInfoList();
		List<ModelBean> modelList1 = order.getModelMap().get(1);
		List<ModelBean> modelList2 = order.getModelMap().get(2);
		List<ModelDetail> detailList = order.getDetailMap().get(2);
		if (modelList2 != null && !modelList2.isEmpty()) {
			for (int i = 0; i < modelList1.size(); i++) {
				ModelBean model1 = modelList1.get(i);
				OrderBean.SampleInfo sampleInfo = null;
				ModelBean model = null;
				ModelDetail detail = null;
				for (int j = 0; j < modelList2.size(); j++) {
					ModelBean model2 = modelList2.get(j);
					if (model1.getClientUniqueId().equals(
							model2.getClientUniqueId())) {
						model = model2;
						detail = detailList.get(j);
						sampleInfo = sampleInfoList.get(j);
						break;
					}
				}
				if (model == null) {
					continue;
				}
				if (model.getModelId() == 4) {
					for (ModelDetail.ModelSection section : detail
							.getSectionList()) {
						Long sectionId = section.getId();
						List<List<ModelDetail.Field>> fieldList = new ArrayList<List<ModelDetail.Field>>();
						sampleInfo.getFieldListMap().put(sectionId, fieldList);
						for (int rowNumber = 1;; rowNumber++) {
							if (StringUtils
									.isEmpty(getSelectedValue(i, sectionId,
											String.valueOf(rowNumber), section
													.getFieldList().get(0)
													.getFieldId()))) {
								break;
							}
							List<ModelDetail.Field> fields = new ArrayList<ModelDetail.Field>();
							fieldList.add(fields);
							for (ModelDetail.Field field : section
									.getFieldList()) {
								ModelDetail.Field field0 = (ModelDetail.Field) field
										.clone();
								field0.setSelectedValue(getSelectedValue(i,
										sectionId, String.valueOf(rowNumber),
										field.getFieldId()));
								fields.add(field0);
							}
						}
					}
				}
			}
			dao.saveOrder(order, 2);
		}
		ResultMessage msg = new ResultMessage();
		msg.setState(ResultMessage.SUCCESS);
		writeJSON(msg);
	}

	private String viewMatrix() throws CloneNotSupportedException {
		OrderBean order = (OrderBean) TRPUtil
				.getFromSession(TRPConstants.CURRENT_ORDER);
		List<OrderBean.MatrixInfo> matrixInfoList = order.getMatrixInfoList();
		List<ModelBean> modelList = order.getModelMap().get(1);
		List<OrderBean.MatrixInfo> newMatrixInfoList = new ArrayList<OrderBean.MatrixInfo>();
		order.setMatrixInfoList(newMatrixInfoList);
		ModelDao modelDao = DaoFactory.getModelDao();
		for (int i = 0; i < modelList.size(); i++) {
			ModelBean model = modelList.get(i);
			if (model.getModelId() == 12) {
				OrderBean.SampleInfo sampleInfo = null;
				if (order.getSampleInfoList() != null) {
					for (OrderBean.SampleInfo sampleInfo0 : order
							.getSampleInfoList()) {
						if (model.getClientUniqueId().equals(
								sampleInfo0.getClientUniqueId())) {
							sampleInfo = sampleInfo0;
							break;
						}
					}
				}
				OrderBean.MatrixInfo matrixInfo = null;
				if (matrixInfoList != null) {
					for (OrderBean.MatrixInfo mi : matrixInfoList) {
						if (mi.getClientUniqueId().equals(
								model.getClientUniqueId())) {
							matrixInfo = mi;
							break;
						}
					}
				}
				if (matrixInfo != null) {
					if (matrixInfo.getFieldList().size() != sampleInfo
							.getFieldListMap().get(5L).size()) {
						matrixInfo = null;
					}
				}
				if (matrixInfo == null) {
					matrixInfo = new OrderBean.MatrixInfo();
					matrixInfo.setClientUniqueId(model.getClientUniqueId());
					List<List<ModelDetail.Field>> recordList = new ArrayList<List<ModelDetail.Field>>();
					matrixInfo.setFieldList(recordList);
					List<ModelDetail.Field> record = null;
					if (model.getModelId() == 12) {
						ModelDetail detail = modelDao.getModelDetail(29L);
						List<ModelDetail.Field> fields = detail
								.getSectionList().get(0).getFieldList();
						for (int j = 0; j < sampleInfo.getFieldListMap()
								.get(5L).size(); j++) {
							record = new ArrayList<ModelDetail.Field>();
							recordList.add(record);
							for (int k = 0; k < fields.size(); k++) {
								ModelDetail.Field field = (ModelDetail.Field) fields
										.get(k).clone();
								if (k == 0) {
									field.setSelectedValue(String.valueOf(j));
								}
								record.add(field);
							}
						}

					}
				}
				newMatrixInfoList.add(matrixInfo);
			}
			TRPUtil.putToSession(TRPConstants.CURRENT_ORDER, order);
		}
		return SUCCESS;
	}

	public void generateMatrix() throws IOException {
		String fileDir = null;
		PropertyBean prop = DaoFactory.getSystemSettingDao().getProperty(5);
		if (prop != null) {
			fileDir = prop.getValue();
		}
		StringBuilder sb = new StringBuilder(fileDir);
		File tmpFile = new File(sb.toString());
		if (!tmpFile.exists()) {
			tmpFile.mkdir();
		}
		sb.append(File.separator).append(orderNumber);
		tmpFile = new File(sb.toString());
		if (!tmpFile.exists()) {
			tmpFile.mkdir();
		}
		sb.append(File.separator).append("matrix");
		tmpFile = new File(sb.toString());
		if (!tmpFile.exists()) {
			tmpFile.mkdir();
		}

		String fileName = "matrix.pdf";
		sb.append(File.separator).append(fileName);
		boolean success = true;
		OrderBean order = (OrderBean) TRPUtil
				.getFromSession(TRPConstants.CURRENT_ORDER);
		Document doc = null;
		try {
			doc = new Document();
			PdfWriter.getInstance(doc, new FileOutputStream(sb.toString()));
			doc.open();
			generateGenernalInfoPDFPage(order, doc);
			List<ModelBean> modelList = order.getModelMap().get(1);
			for (int idx = 0; idx < modelList.size(); idx++) {
				generateTechInfoPDFPage(order, idx, doc);
				// generateSampleInfoPDFPage(order, doc);
				generateMatrixPDF(order, idx, doc);
			}

		} catch (Exception e) {
			success = false;
			log.warn(e);
		} finally {
			if (doc != null) {
				doc.close();
			}
		}
		ResultMessage msg = new ResultMessage();
		msg.setState(success ? ResultMessage.SUCCESS : ResultMessage.FAILED);
		writeJSON(msg);
	}

	private void generateMatrixPDF(OrderBean order, int idx, Document doc)
			throws IOException {
		List<ModelBean> modelList = order.getModelMap().get(1);
		if (modelList != null && !modelList.isEmpty()) {
			try {
				ModelBean model = modelList.get(idx);
				if (model.getModelId() == 13 || model.getModelId() == 14) {
					return;
				}
				List<Map<String, String>> matrix = getMatrix0(order, idx);
				List<Map<String, String>> spMatrix = getSpareParts0(order, idx);
				BaseFont bf = BaseFont.createFont("STSong-Light",
						"UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
				Font font = new Font(bf, 7);
				doc.newPage();
				Phrase p = new Phrase((idx + 1) + ".Matrix Information["
						+ model.getModelName() + "]");
				doc.add(p);
				PdfPTable table = null;
				if (model.getModelId() == 12) {
					// draw headers
					String[] headers = { "Test No", "Test Temp",
							"Inflator Type", "Side", "Ignition Current:(A)",
							"Ignition Current Duration:(ms)",
							"Ignition Resistance",
							"Time from removal to ignition:(s)",
							"Storage Temperature", "Min", "Max",
							"Restorage Time(min)", "Module mounting time(s)",
							"Test Temperature(°C)", "Comments" };
					String[] headerIndices = { "testTemp", "inflatorType",
							"side", "ignitionC", "ignitionCD", "ignitionR",
							"timeFRTI", "storageTemp", "min", "max",
							"restorageTime", "moduleMountingTime",
							"testTemperature", "comments" };
					// draw table header
					table = new PdfPTable(headers.length);
					table.setWidthPercentage(100);
					PdfPCell cell = null;
					for (int j = 0; j < headers.length; j++) {
						String header = headers[j];
						if (j == 9) {
							PdfPTable tmpTable = new PdfPTable(2);
							PdfPCell tmpCell = new PdfPCell(new Phrase(
									"Storage time(h)", font));
							tmpCell.setColspan(2);
							tmpTable.addCell(tmpCell);
							tmpCell = new PdfPCell(new Phrase(header, font));
							tmpTable.addCell(tmpCell);
							tmpCell = new PdfPCell(
									new Phrase(headers[10], font));
							tmpTable.addCell(tmpCell);
							cell = new PdfPCell(tmpTable);
							cell.setColspan(2);
						} else if (j == 10) {
							continue;
						} else {
							cell = new PdfPCell(new Phrase(header, font));
						}
						cell.setBackgroundColor(Color.GRAY);
						table.addCell(cell);
					}
					if (matrix != null) {
						for (int k = 0; k < matrix.size(); k++) {
							Map<String, String> record = matrix.get(k);
							cell = new PdfPCell(new Phrase(String
									.valueOf(k + 1), font));
							table.addCell(cell);
							for (String headerIdx : headerIndices) {
								cell = new PdfPCell(new Phrase(record
										.get(headerIdx) == null ? "N/A"
										: record.get(headerIdx), font));
								table.addCell(cell);
							}
						}
					}

					doc.add(table);
					p = new Phrase("Spare Parts:", font);
					doc.add(p);
					table = new PdfPTable(headers.length - 1);
					table.setWidthPercentage(100);
					for (int j = 0; j < headers.length - 1; j++) {
						String header = headers[j];
						if (j == 9) {
							PdfPTable tmpTable = new PdfPTable(2);
							PdfPCell tmpCell = new PdfPCell(new Phrase(
									"Storage time(h)", font));
							tmpCell.setColspan(2);
							tmpTable.addCell(tmpCell);
							tmpCell = new PdfPCell(new Phrase(header, font));
							tmpTable.addCell(tmpCell);
							tmpCell = new PdfPCell(
									new Phrase(headers[10], font));
							tmpTable.addCell(tmpCell);
							cell = new PdfPCell(tmpTable);
							cell.setColspan(2);
						} else if (j == 10) {
							continue;
						} else {
							cell = new PdfPCell(new Phrase(header, font));
						}
						cell.setBackgroundColor(Color.GRAY);
						table.addCell(cell);
					}
					if (spMatrix != null) {
						for (int k = 0; k < spMatrix.size(); k++) {
							Map<String, String> record = spMatrix.get(k);
							cell = new PdfPCell(new Phrase(String
									.valueOf(k + 1), font));
							table.addCell(cell);
							for (int kk = 0; kk < headerIndices.length - 1; kk++) {
								String headerIdx = headerIndices[kk];
								cell = new PdfPCell(new Phrase(record
										.get(headerIdx) == null ? "N/A"
										: record.get(headerIdx), font));
								table.addCell(cell);
							}
						}
					}
				} else if (model.getModelId() == 20 || model.getModelId() == 21
						|| model.getModelId() == 22 || model.getModelId() == 23) {
					// draw headers
					String[] headers = null;
					String[] headerIndices = null;
					if (model.getModelId() == 20) {
						headers = new String[] { "No.", "Ignition Current (A)",
								"Current Duration (ms)", "Frame Per Second",
								"Video Record Time(ms)", "Temperature(°C)",
								"Storage time(h)", "Dual Stage inflator",
								"Stage Delay(ms)", "Length(mm)", "Width(mm)",
								"Impact Mass(kg)", "Velocity", "Test Quantity",
								"Position", "Temperature", "Module Parameter" };
						headerIndices = new String[] { "ignitionC",
								"currentDur", "framePerSec", "videoRecTime",
								"temp", "storageTime", "dualStageInflator",
								"stageD", "length", "width", "impactMass",
								"Velocity", "TestQuantity", "Position",
								"Temperature", "ModuleParameter" };
					} else if (model.getModelId() == 21) {
						headers = new String[] { "No.", "Ignition Current (A)",
								"Current Duration (ms)", "Frame Per Second",
								"Video Record Time(ms)", "Temperature(°C)",
								"Storage time(h)", "Dual Stage inflator",
								"Stage Delay(ms)", "Impact Type", "Velocity",
								"Test Quantity", "Position", "Temperature",
								"Module Parameter" };
						headerIndices = new String[] { "ignitionC",
								"currentDur", "framePerSec", "videoRecTime",
								"temp", "storageTime", "dualStageInflator",
								"stageD", "impactType", "Velocity",
								"TestQuantity", "Position", "Temperature",
								"ModuleParameter" };
					} else if (model.getModelId() == 22) {
						headers = new String[] { "No.", "Ignition Current (A)",
								"Current Duration (ms)", "Frame Per Second",
								"Video Record Time(ms)", "Temperature(°C)",
								"Storage time(h)", "Dual Stage inflator",
								"Stage Delay(ms)", "Impact Mass(kg)",
								"Column Angle(°)", "Velocity", "Test Quantity",
								"Position", "Temperature", "Module Parameter" };
						headerIndices = new String[] { "ignitionC",
								"currentDur", "framePerSec", "videoRecTime",
								"temp", "storageTime", "dualStageInflator",
								"stageD", "impactMass", "columnAngle",
								"Velocity", "TestQuantity", "Position",
								"Temperature", "ModuleParameter" };
					} else if (model.getModelId() == 23) {
						headers = new String[] { "No.", "Ignition Current (A)",
								"Current Duration (ms)", "Frame Per Second",
								"Video Record Time(ms)", "Temperature(°C)",
								"Storage time(h)", "Dual Stage inflator",
								"Stage Delay(ms)", "Length(mm)", "Width(mm)",
								"Impact Mass(kg)", "Push Distance",
								"Test Quantity", "Position", "Temperature",
								"Module Parameter" };
						headerIndices = new String[] { "ignitionC",
								"currentDur", "framePerSec", "videoRecTime",
								"temp", "storageTime", "dualStageInflator",
								"stageD", "length", "width", "impactMass",
								"PushDistance", "TestQuantity", "Position",
								"Temperature", "ModuleParameter" };
					}

					// draw table header
					table = new PdfPTable(headers.length);
					table.setWidthPercentage(100);
					PdfPCell cell = null;
					for (int j = 0; j < headers.length; j++) {
						String header = headers[j];
						if ((model.getModelId() == 20 || model.getModelId() == 23)
								&& j == 9) {
							PdfPTable tmpTable = new PdfPTable(2);
							PdfPCell tmpCell = new PdfPCell(new Phrase(
									"Impact Dimension", font));
							tmpCell.setColspan(2);
							tmpTable.addCell(tmpCell);
							tmpCell = new PdfPCell(new Phrase(header, font));
							tmpTable.addCell(tmpCell);
							tmpCell = new PdfPCell(
									new Phrase(headers[10], font));
							tmpTable.addCell(tmpCell);
							cell = new PdfPCell(tmpTable);
							cell.setColspan(2);
						} else if ((model.getModelId() == 20 || model
								.getModelId() == 23)
								&& j == 10) {
							continue;
						} else {
							cell = new PdfPCell(new Phrase(header, font));
						}
						cell.setBackgroundColor(Color.GRAY);
						table.addCell(cell);
					}

					// draw table
					if (matrix != null) {
						for (int k = 0; k < matrix.size(); k++) {
							Map<String, String> record = matrix.get(k);
							cell = new PdfPCell(new Phrase(String
									.valueOf(k + 1), font));
							table.addCell(cell);
							for (String headerIdx : headerIndices) {
								cell = new PdfPCell(new Phrase(record
										.get(headerIdx) == null ? "N/A"
										: record.get(headerIdx), font));
								table.addCell(cell);
							}
						}
					}
				}
				doc.add(table);
			} catch (Exception e) {
				log.warn(e);
			}
		}
	}

	private void generateTechInfoPDFPage(OrderBean order, int idx, Document doc)
			throws Exception {
		String methodName = "generateTechInfoPDFPage";
		log.enter(methodName);
		List<ModelDetail> detailList = order.getDetailMap().get(1);
		List<ModelBean> modelList = order.getModelMap().get(1);
		BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",
				BaseFont.NOT_EMBEDDED);
		Font font = new Font(bf, 8);
		if (modelList != null && !modelList.isEmpty()) {
			try {
				doc.newPage();
				ModelBean model = modelList.get(idx);
				ModelDetail detail = detailList.get(idx);
				Phrase p = new Phrase((idx + 1) + ".Technical Information["
						+ model.getModelName() + "]");
				doc.add(p);
				for (ModelDetail.ModelSection section : detail.getSectionList()) {
					// draw section content
					PdfPTable table = new PdfPTable(section.getCols());
					table.setWidthPercentage(100);
					// draw section name
					PdfPCell cell = null;
					cell = new PdfPCell(new Phrase(section.getName(), font));
					cell.setColspan(section.getCols());
					cell.setBackgroundColor(Color.GRAY);
					cell.setFixedHeight(15);
					table.addCell(cell);
					String imgUrl = null;
					List<Long> skipFields = new ArrayList<Long>();
					skipFields.add(337L);
					skipFields.add(338L);
					skipFields.add(339L);
					skipFields.add(308L);
					skipFields.add(309L);
					skipFields.add(310L);
					skipFields.add(192L);
					skipFields.add(193L);
					skipFields.add(194L);
					skipFields.add(332L);
					skipFields.add(333L);
					skipFields.add(334L);
					// static deployment
					skipFields.add(352L);
					skipFields.add(353L);
					skipFields.add(354L);
					skipFields.add(355L);
					for (int k = 0; k < section.getFieldList().size(); k++) {
						cell = null;
						String text = null;
						boolean skip = true;
						ModelDetail.Field field = section.getFieldList().get(k);
						if (field.getFieldType() == 0
								|| field.getFieldType() == 11) {
							skip = false;
							text = field.getSelectedValue();
							if (StringUtils.isEmpty(text)) {
								text = field.getFieldName();
							}
							if (text != null) {
								text = text.replaceAll("<br>", "\n")
										.replaceAll("&bull;", "").replaceAll(
												"&Oslash;", "0");
							}
						} else if (field.getFieldType() == 1
								|| field.getFieldType() == 2
								|| field.getFieldType() == 3
								|| field.getFieldType() == 4
								|| field.getFieldType() == 5
								|| field.getFieldType() == 6
								|| field.getFieldType() == 7
								|| field.getFieldType() == 10) {
							skip = false;
							StringBuilder sb = new StringBuilder();
							if (!StringUtils.isEmpty(field.getFieldName())) {
								sb.append(field.getFieldName()).append(
										TRPConstants.COLON);
							}
							if (!StringUtils.isEmpty(field.getSelectedValue())) {
								sb.append(field.getSelectedValue().replaceAll(
										"&acute;", "'"));
							}
							if (!StringUtils.isEmpty(field.getRelatedValue())) {
								if ("others".equalsIgnoreCase(field
										.getSelectedValue())) {
									sb.append(section.getFieldList().get(k + 1)
											.getSelectedValue());
								}
								try {
									skipFields.add(Long.parseLong(field
											.getRelatedValue()));
								} catch (Exception e) {
								}
							}
							text = sb.toString();
						} else if (field.getFieldType() == 33) {
							skip = false;
							List<JSONObject> headers = new ArrayList<JSONObject>();
							List<String> headerKeys = new ArrayList<String>();
							String relValue = field.getRelatedValue();
							JSONObject json = JSONObject.fromObject(relValue);
							JSONArray jsonClms = json.getJSONArray("clms");
							for (int kk = 0; kk < jsonClms.size(); kk++) {
								JSONObject obj = jsonClms.getJSONObject(kk);
								JSONArray items = null;
								try {
									items = obj.getJSONArray("items");
								} catch (Exception e) {
								}
								headers.add(obj);
								if (items == null) {
									headerKeys.add(obj.get("n").toString()
											.replaceAll(" ", ""));
								} else {
									for (int ii = 0; ii < items.size(); ii++) {
										headerKeys.add(items.getJSONObject(ii)
												.get("n").toString()
												.replaceAll(" ", ""));
									}
								}

							}
							PdfPTable tmpTable = new PdfPTable(headerKeys
									.size());
							PdfPCell tmpCell = null;
							for (JSONObject header : headers) {
								JSONArray items = null;
								try {
									items = header.getJSONArray("items");
								} catch (Exception e) {
								}
								if (items == null) {
									tmpCell = new PdfPCell(new Phrase(header
											.getString("n").toString()
											.replaceAll("&Oslash;", "0"), font));
								} else {
									PdfPTable tmpTable0 = new PdfPTable(items
											.size());
									tmpCell = new PdfPCell(new Phrase(header
											.getString("n").toString()
											.replaceAll("&Oslash;", "0"), font));
									tmpCell.setColspan(items.size());
									tmpCell
											.setBackgroundColor(Color.LIGHT_GRAY);
									tmpTable0.addCell(tmpCell);
									for (int ii = 0; ii < items.size(); ii++) {
										tmpCell = new PdfPCell(new Phrase(items
												.getJSONObject(ii).get("n")
												.toString().replaceAll(
														"&Oslash;", "0"), font));
										tmpCell
												.setBackgroundColor(Color.LIGHT_GRAY);
										tmpTable0.addCell(tmpCell);
									}
									tmpCell = new PdfPCell(tmpTable0);
									tmpCell.setColspan(items.size());
								}
								tmpCell.setBackgroundColor(Color.LIGHT_GRAY);
								tmpTable.addCell(tmpCell);
							}
							List<JSONObject> jsonVals = ModelUtil
									.parseMatrix(field);
							for (int kk = 0; kk < jsonVals.size(); kk++) {
								JSONObject jsonVal = jsonVals.get(kk);
								for (int jj = 0; jj < headerKeys.size(); jj++) {
									tmpCell = new PdfPCell(new Phrase(jsonVal
											.getString(headerKeys.get(jj)),
											font));
									tmpTable.addCell(tmpCell);
								}
							}
							tmpCell = new PdfPCell(tmpTable);
							tmpCell.setColspan(field.getCols());
							table.addCell(tmpCell);
						} else if (field.getFieldType() == 8
								|| field.getFieldType() == 31
								|| field.getFieldType() == 32) {
							skip = false;
						}
						if (field.getFieldId() == 246L) {
							if ("Coordinates".equals(field.getSelectedValue())) {
								skipFields.add(274L);
							} else {
								skipFields.add(247L);
								skipFields.add(248L);
								skipFields.add(273L);
							}
						}
						if (field.getFieldId() == 288L) {
							if ("Coordinates".equals(field.getSelectedValue())) {
								skipFields.add(292L);
							} else {
								skipFields.add(289L);
								skipFields.add(290L);
								skipFields.add(291L);
							}
						}
						if (field.getFieldId() == 300L) {
							if ("Coordinates".equals(field.getSelectedValue())) {
								skipFields.add(304L);
							} else {
								skipFields.add(301L);
								skipFields.add(302L);
								skipFields.add(303L);
							}
						}
						if (field.getFieldId() == 324L) {
							if ("Coordinates".equals(field.getSelectedValue())) {
								skipFields.add(328L);
							} else {
								skipFields.add(325L);
								skipFields.add(326L);
								skipFields.add(327L);
							}
						}
						if (!skip && !skipFields.contains(field.getFieldId())) {
							if (field.getFieldId() == 128) {
								ModelDetail.Field tmpField = section
										.getFieldList().get(k - 1);
								if ("Default".equalsIgnoreCase(tmpField
										.getSelectedValue())) {
									imgUrl = "image2.JPG";
								}
								if (imgUrl != null) {
									tmpField = section.getFieldList()
											.get(k + 6);
									if (!"same side view"
											.equalsIgnoreCase(tmpField
													.getSelectedValue())) {
										imgUrl = "image1.JPG";
									}
								}
								if (imgUrl != null) {
									String imgPath = ServletActionContext
											.getServletContext().getRealPath(
													"/images");
									Image awtImage = Image.getInstance(imgPath
											+ File.separator + imgUrl);
									awtImage.scaleToFit(100, 200);
									cell = new PdfPCell(awtImage, true);
								} else {
									cell = new PdfPCell(new Phrase("", font));
								}
								cell.setRowspan(field.getRows());
								imgUrl = null;
							} else if (field.getFieldId() == 377) {
								idx = text.indexOf("<img");
								text = text.substring(0, idx);
								cell = new PdfPCell(new Phrase(text, font));
								table.addCell(cell);
								String imgPath = ServletActionContext
										.getServletContext().getRealPath(
												"/images");
								Image awtImage = Image.getInstance(imgPath
										+ File.separator + "foluma1.png");
								awtImage.scaleToFit(307, 62);
								cell = new PdfPCell(awtImage, true);
							} else {
								text = text == null ? "" : text;
								cell = new PdfPCell(new Phrase(text, font));
								cell.setColspan(field.getCols());
								cell.setRowspan(field.getRows());
							}
							table.addCell(cell);
						}
					}
					doc.add(table);
				}

			} catch (Exception e) {
				log.warn(e);
			}
		}
		log.exit(methodName);
	}

	private void generateGenernalInfoPDFPage(OrderBean order, Document doc)
			throws IOException {
		String methodName = "generateGenernalInfoPDFPage";
		log.enter(methodName);
		try {
			BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",
					BaseFont.NOT_EMBEDDED);
			Font font = new Font(bf, 8);
			UserBean user = order.getUser();
			UserBean testUser = order.getGeneralInfo() == null ? null : order
					.getGeneralInfo().getTestUser();
			UserBean vvUser = order.getGeneralInfo() == null ? null : order
					.getGeneralInfo().getVvUser();
			Phrase p = new Phrase("General Information");
			doc.add(p);
			PdfPTable table = new PdfPTable(6);
			table.setWidthPercentage(100);
			PdfPCell cell = new PdfPCell(new Phrase("TRP Number", font));
			table.addCell(cell);
			cell = new PdfPCell(new Phrase(order.getOrderNumber(), font));
			cell.setColspan(2);
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("Project Name", font));
			cell.setRowspan(4);
			table.addCell(cell);
			cell = new PdfPCell(new Phrase("Customer: "
					+ (order.getGeneralInfo() == null ? "N/A" : order
							.getGeneralInfo().getCustomer()), font));
			cell.setColspan(2);
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("Created Date", font));
			table.addCell(cell);
			cell = new PdfPCell(new Phrase(TRPConstants.DATE_FORMAT
					.format(order.getCreatedDate()), font));
			cell.setColspan(2);
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("Project: "
					+ (order.getGeneralInfo() == null ? "N/A" : order
							.getGeneralInfo().getProject()), font));
			cell.setColspan(2);
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("Phase", font));
			table.addCell(cell);
			cell = new PdfPCell(new Phrase(
					order.getGeneralInfo() == null ? "N/A" : order
							.getGeneralInfo().getPhase(), font));
			cell.setColspan(2);
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("Product: "
					+ (order.getGeneralInfo() == null ? "N/A" : order
							.getGeneralInfo().getProduct()), font));
			cell.setColspan(2);
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("Test Purpose", font));
			table.addCell(cell);
			cell = new PdfPCell(new Phrase(
					order.getGeneralInfo() == null ? "N/A" : order
							.getGeneralInfo().getTestPurpose(), font));
			cell.setColspan(2);
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("Plant: "
					+ (order.getGeneralInfo() == null ? "N/A" : order
							.getGeneralInfo().getPlant()), font));
			cell.setColspan(2);
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("Applicant", font));
			cell.setRowspan(2);
			table.addCell(cell);
			cell = new PdfPCell(new Phrase("Name", font));
			table.addCell(cell);
			cell = new PdfPCell(new Phrase(user.getName(), font));
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("Project Number", font));
			table.addCell(cell);
			cell = new PdfPCell(new Phrase(
					order.getGeneralInfo() == null ? "N/A" : order
							.getGeneralInfo().getProjectNumber(), font));
			cell.setColspan(2);
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("Mobile/Tel", font));
			table.addCell(cell);
			cell = new PdfPCell(new Phrase("Tel:" + user.getTel() + " Mobile:"
					+ user.getMobile(), font));
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("Payer", font));
			table.addCell(cell);
			cell = new PdfPCell(new Phrase(
					order.getGeneralInfo() == null ? "N/A" : (order
							.getGeneralInfo().getPayer() == null ? "N/A"
							: order.getGeneralInfo().getPayer()), font));
			cell.setColspan(2);
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("Test Engineer", font));
			cell.setRowspan(2);
			table.addCell(cell);
			cell = new PdfPCell(new Phrase("Name", font));
			table.addCell(cell);
			cell = new PdfPCell(new Phrase(testUser == null ? "N/A" : testUser
					.getName(), font));
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("Report Mode", font));
			table.addCell(cell);
			cell = new PdfPCell(new Phrase(
					order.getGeneralInfo() == null ? "N/A" : order
							.getGeneralInfo().getReportMode(), font));
			cell.setColspan(2);
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("Mobile/Tel", font));
			table.addCell(cell);
			cell = new PdfPCell(new Phrase(testUser == null ? "N/A" : ("Tel:"
					+ testUser.getTel() + " Mobile:" + testUser.getMobile()),
					font));
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("Report distribution", font));
			table.addCell(cell);
			cell = new PdfPCell(new Phrase(
					order.getGeneralInfo() == null ? "N/A" : order
							.getGeneralInfo().getReportDistribution(), font));
			cell.setColspan(2);
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("V&V Engineer", font));
			cell.setRowspan(2);
			table.addCell(cell);
			cell = new PdfPCell(new Phrase("Name", font));
			table.addCell(cell);
			cell = new PdfPCell(new Phrase(vvUser == null ? "N/A" : vvUser
					.getName(), font));
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("", font));
			cell.setColspan(3);
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("Mobile/Tel", font));
			table.addCell(cell);
			cell = new PdfPCell(new Phrase(vvUser == null ? "N/A" : ("Tel:"
					+ vvUser.getTel() + " Mobile:" + vvUser.getMobile()), font));
			table.addCell(cell);

			cell = new PdfPCell(new Phrase("", font));
			cell.setColspan(3);
			table.addCell(cell);
			doc.add(table);
		} catch (Exception e) {
			log.warn(e);
		}
		log.exit(methodName);
	}

	private String getSelectedValue(int i, long sectionId, String rowNumber,
			long fieldId) {
		StringBuilder sb = new StringBuilder();
		sb.append("p_").append(i).append("_").append(sectionId).append("_")
				.append(rowNumber).append("_").append(fieldId);
		String param = getParamFromRequest(sb.toString());
		if (param != null) {
			param = param.replaceAll("null", "");
		}
		return param;
	}

	public void updateOrderTemplate() throws IOException {
		ResultMessage ret = new ResultMessage();
		try {
			UserBean user = (UserBean) TRPUtil
					.getFromSession(TRPConstants.CURRENT_USER);
			long userId = user == null ? -1 : user.getUserId();
			String isPublicStr = getParamFromRequest("isPublic");
			String templateIdStr = getParamFromRequest("templateId");
			String templateName = getParamFromRequest("templateName");
			long templateId = Long.parseLong(templateIdStr);
			boolean isPrivate = "false".equalsIgnoreCase(isPublicStr);
			OrderTemplateBean template = new OrderTemplateBean();
			template.setTemplateId(templateId);
			template.setTemplateName(templateName);
			template.setPrivate(isPrivate);
			OrderDao dao = DaoFactory.getOrderDao();
			long templateId2 = dao.checkOrderTemplate(templateName, userId);
			if (templateId2 > -1 && templateId != templateId2) {
				ret.setState(ResultMessage.FAILED);
				ret.setMessage("Template Name:" + templateName
						+ " already exists.");
			} else {
				boolean flag = dao.saveOrderTemplate(template);
				if (flag) {
					ret.setMessage("template updated.");
				} else {
					ret.setState(ResultMessage.FAILED);
					ret.setMessage("operation failed,please try again.");
				}
			}
		} catch (Exception e) {
			ret.setState(ResultMessage.FAILED);
			ret.setMessage(e.getMessage());
		}
		writeJSON(ret);
	}

	public void saveOrderTemplate() throws IOException {
		ResultMessage ret = new ResultMessage();
		try {
			String isPublicStr = getParamFromRequest("isPublic");
			String orderIdStr = getParamFromRequest("orderId");
			String templateName = getParamFromRequest("templateName");
			long orderId = Long.parseLong(orderIdStr);
			boolean isPublic = "true".equalsIgnoreCase(isPublicStr);
			UserBean user = (UserBean) TRPUtil
					.getFromSession(TRPConstants.CURRENT_USER);
			long userId = user == null ? -1 : user.getUserId();
			OrderDao dao = DaoFactory.getOrderDao();
			long templateId = dao.checkOrderTemplate(templateName, userId);
			if (templateId > -1) {
				ret.setState(ResultMessage.FAILED);
				ret.setMessage("Template Name:" + templateName
						+ " already exists.");
			} else {
				boolean flag = dao.saveOrderTemplate(templateName, orderId,
						isPublic, userId);
				if (flag) {
					ret.setMessage("template saved.");
				} else {
					ret.setState(ResultMessage.FAILED);
					ret.setMessage("operation failed,please try again.");
				}
			}
		} catch (Exception e) {
			ret.setState(ResultMessage.FAILED);
			ret.setMessage(e.getMessage());
		}
		writeJSON(ret);
	}

	public void getOrderTemplates() throws IOException {
		UserBean user = (UserBean) TRPUtil
				.getFromSession(TRPConstants.CURRENT_USER);
		long userId = user == null ? -1 : user.getUserId();
		OrderDao dao = DaoFactory.getOrderDao();
		String cateStr = getParamFromRequest("category");
		int category = -1;
		try {
			category = Integer.parseInt(cateStr);
		} catch (NumberFormatException e) {
			log.warn(e);
		}
		List<OrderTemplateBean> templateList = dao.getOrderTemplates(userId,
				category);
		writeJSON(templateList);
	}

	public String createOrderFromTemplate() {
		UserBean user = (UserBean) TRPUtil
				.getFromSession(TRPConstants.CURRENT_USER);
		String orderId = getParamFromRequest("orderId");
		OrderDao dao = DaoFactory.getOrderDao();
		OrderBean order = null;
		try {
			order = dao.getOrder(Long.parseLong(orderId), true);
		} catch (Exception e) {
			log.warn(e);
		}
		if (order != null) {
			order.setOrderId(-1);
			order.setUser(user);
			order.setCreatedDate(new Date());
			String orderNumber = dao
					.getAutoNumber(TRPConstants.AUTO_NUMBER_TRP);
			order.setOrderNumber(orderNumber);
			order.setSampleInfoList(null);
			order.setMatrixInfoList(null);
			List<ModelBean> modelList = order.getModelMap().get(1);
			if (modelList != null) {
				for (ModelBean model : modelList) {
					model.setClientUniqueId(model.getClientUniqueId()
							+ order.getOrderNumber());
				}
			}
			TRPUtil.putToSession(TRPConstants.CURRENT_ORDER, order);
			TRPUtil.removeFromSession("modelList");
			TRPUtil.putToSession(TRPConstants.CURRENT_MODEL_STATUS, 1);
		}
		return SUCCESS;
	}

	private String generateProjectName(OrderBean order) {
		return new StringBuilder().append(order.getGeneralInfo().getCustomer())
				.append(TRPConstants.COMMA).append(
						order.getGeneralInfo().getProject()).append(
						TRPConstants.COMMA).append(
						order.getGeneralInfo().getProduct()).append(
						TRPConstants.COMMA).append(
						order.getGeneralInfo().getPlant()).toString();
	}

	private String generateViewOrderUrl(OrderBean order)
			throws UnknownHostException {
		HttpServletRequest request = ServletActionContext.getRequest();
		return new StringBuffer().append(request.getScheme()).append("://")
				.append(java.net.InetAddress.getLocalHost().getHostAddress())
				.append(":").append(request.getServerPort()).append(
						"/trp/viewOrder.action?orderId=").append(orderId)
				.toString();
	}

}
